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

// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.

#include "Airavata.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

using namespace  ::apache::airavata::api;

class AiravataHandler : virtual public AiravataIf {
 public:
  AiravataHandler() {
    // Your initialization goes here
  }

  /**
   * Verify if User Exists within Airavata.
   * 
   * @param gatewayId
   * 
   *  @param userName
   * 
   * @return true/false
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param userName
   */
  bool isUserExists(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& userName) {
    // Your implementation goes here
    printf("isUserExists\n");
  }

  /**
   * Register a Gateway with Airavata.
   * 
   * @param gateway
   *    The gateway data model.
   * 
   * @return gatewayId
   *   Th unique identifier of the  newly registered gateway.
   * 
   * 
   * 
   * @param authzToken
   * @param gateway
   */
  void addGateway(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::workspace::Gateway& gateway) {
    // Your implementation goes here
    printf("addGateway\n");
  }

  /**
   * Get all users in the gateway
   * 
   * @param gatewayId
   *    The gateway data model.
   * 
   * @return users
   *   list of usernames of the users in the gateway
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getAllUsersInGateway(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllUsersInGateway\n");
  }

  /**
   * Update previously registered Gateway metadata.
   * 
   * @param gatewayId
   *    The gateway Id of the Gateway which require an update.
   * 
   * @return gateway
   *    Modified gateway obejct.
   * 
   * @exception AiravataClientException
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param updatedGateway
   */
  bool updateGateway(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::workspace::Gateway& updatedGateway) {
    // Your implementation goes here
    printf("updateGateway\n");
  }

  /**
   * Get Gateway details by providing gatewayId
   * 
   * @param gatewayId
   *    The gateway Id of the Gateway.
   * 
   * @return gateway
   *    Gateway obejct.
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getGateway( ::apache::airavata::model::workspace::Gateway& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getGateway\n");
  }

  /**
   * Delete a Gateway
   * 
   * @param gatewayId
   *    The gateway Id of the Gateway to be deleted.
   * 
   * @return boolean
   *    Boolean identifier for the success or failure of the deletion operation.
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  bool deleteGateway(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("deleteGateway\n");
  }

  /**
   * Get All the Gateways Connected to Airavata.
   * 
   * 
   * @param authzToken
   */
  void getAllGateways(std::vector< ::apache::airavata::model::workspace::Gateway> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getAllGateways\n");
  }

  /**
   * Check for the Existance of a Gateway within Airavata
   * 
   * @param gatewayId
   *   Provide the gatewayId of the gateway you want to check the existancy
   * 
   * @return boolean
   *   Boolean idetifier for the existance or non-existane of the gatewayId
   * 
   * @return gatewayId
   *   return the gatewayId of the existing gateway.
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  bool isGatewayExist(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("isGatewayExist\n");
  }

  /**
   *   * API methods to retrieve notifications
   * *
   * 
   * @param authzToken
   * @param notification
   */
  void createNotification(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::workspace::Notification& notification) {
    // Your implementation goes here
    printf("createNotification\n");
  }

  bool updateNotification(const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::workspace::Notification& notification) {
    // Your implementation goes here
    printf("updateNotification\n");
  }

  bool deleteNotification(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& notificationId) {
    // Your implementation goes here
    printf("deleteNotification\n");
  }

  void getNotification( ::apache::airavata::model::workspace::Notification& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& notificationId) {
    // Your implementation goes here
    printf("getNotification\n");
  }

  void getAllNotifications(std::vector< ::apache::airavata::model::workspace::Notification> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllNotifications\n");
  }

  /**
   * Generate and Register SSH Key Pair with Airavata Credential Store.
   * 
   * @param description
   *    The description field for a credential type, all type of credential can have a description.
   * 
   * @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 description
   */
  void generateAndRegisterSSHKeys(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& description) {
    // Your implementation goes here
    printf("generateAndRegisterSSHKeys\n");
  }

  /**
   * Generate and Register Username PWD Pair with Airavata Credential Store.
   * 
   * @param loginUserName
   * 
   * @param password
   * 
   * @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 loginUserName
   * @param password
   * @param description
   */
  void registerPwdCredential(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& loginUserName, const std::string& password, const std::string& description) {
    // Your implementation goes here
    printf("registerPwdCredential\n");
  }

  void getCredentialSummary( ::CredentialSummary& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& tokenId) {
    // Your implementation goes here
    printf("getCredentialSummary\n");
  }

  void getAllCredentialSummaries(std::vector< ::CredentialSummary> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::SummaryType::type type) {
    // Your implementation goes here
    printf("getAllCredentialSummaries\n");
  }

  bool deleteSSHPubKey(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataCredStoreToken) {
    // Your implementation goes here
    printf("deleteSSHPubKey\n");
  }

  bool deletePWDCredential(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataCredStoreToken) {
    // Your implementation goes here
    printf("deletePWDCredential\n");
  }

  /**
   * 
   * 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
   */
  void createProject(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::workspace::Project& project) {
    // Your implementation goes here
    printf("createProject\n");
  }

  /**
   * 
   * Update an Existing Project
   * 
   * @param projectId
   *    The projectId of the project needed an update.
   * 
   * @return void
   *    Currently this does not return any value.
   * 
   * 
   * 
   * @param authzToken
   * @param projectId
   * @param updatedProject
   */
  void updateProject(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& projectId, const  ::apache::airavata::model::workspace::Project& updatedProject) {
    // Your implementation goes here
    printf("updateProject\n");
  }

  /**
   * 
   * Get a Project by ID
   *    This method is to obtain a project by providing a projectId.
   * 
   * @param projectId
   *    projectId of the project you require.
   * 
   * @return project
   *    project data model will be returned.
   * 
   * 
   * 
   * @param authzToken
   * @param projectId
   */
  void getProject( ::apache::airavata::model::workspace::Project& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& projectId) {
    // Your implementation goes here
    printf("getProject\n");
  }

  /**
   * 
   * Delete a Project
   *    This method is used to delete an existing Project.
   * 
   * @param projectId
   *    projectId of the project you want to delete.
   * 
   * @return boolean
   *    Boolean identifier for the success or failure of the deletion operation.
   * 
   *    NOTE: This method is not used within gateways connected with Airavata.
   * 
   * 
   * 
   * @param authzToken
   * @param projectId
   */
  bool deleteProject(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& projectId) {
    // Your implementation goes here
    printf("deleteProject\n");
  }

  /**
   * 
   * Get All User Projects
   * Get all Project for the 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
   */
  void getUserProjects(std::vector< ::apache::airavata::model::workspace::Project> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& userName, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("getUserProjects\n");
  }

  /**
   * 
   * Search User Projects
   * Search and get all Projects for user by project description or/and project name  with pagination.
   * Results will be ordered based on creation time DESC.
   * 
   * @param gatewayId
   *    The unique identifier of the gateway making the request.
   * 
   * @param userName
   *    The identifier of the user.
   * 
   * @param filters
   *    Map of multiple filter criteria. Currenlt search filters includes Project Name and Project Description
   * 
   * @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 filters
   * @param limit
   * @param offset
   */
  void searchProjects(std::vector< ::apache::airavata::model::workspace::Project> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& userName, const std::map< ::apache::airavata::model::experiment::ProjectSearchFields::type, std::string> & filters, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("searchProjects\n");
  }

  /**
   * Search Experiments.
   * 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 user requesting the search function.
   * 
   * @param filters
   *       Map of multiple filter criteria. Currenlt search filters includes Experiment Name, Description, Application, etc....
   * 
   * @param limit
   *       Amount of results to be fetched.
   * 
   * @param offset
   *       The starting point of the results to be fetched.
   * 
   * @return ExperimentSummaryModel
   *    List of experiments for the given search filter. Here only the Experiment summary will be returned.
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param userName
   * @param filters
   * @param limit
   * @param offset
   */
  void searchExperiments(std::vector< ::apache::airavata::model::experiment::ExperimentSummaryModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& userName, const std::map< ::apache::airavata::model::experiment::ExperimentSearchFields::type, std::string> & filters, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("searchExperiments\n");
  }

  /**
   * 
   * Get Experiment Statistics
   * Get Experiment Statisitics for a given gateway for a specific time period. This feature is available only for admins of a particular gateway. Gateway admin access is managed by the user roles.
   * 
   * @param gatewayId
   *       Unique identifier of the gateway making the request to fetch statistics.
   * 
   * @param fromTime
   *       Starting date time.
   * 
   * @param toTime
   *       Ending data time.
   * 
   * @param userName
   *       Gateway username substring with which to further filter statistics.
   * 
   * @param applicationName
   *       Application id substring with which to further filter statistics.
   * 
   * @param resourceHostName
   *       Hostname id substring with which to further filter statistics.
   * 
   * @param limit
   *       Amount of results to be fetched.
   * 
   * @param offset
   *       The starting point of the results to be fetched.
   * 
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param fromTime
   * @param toTime
   * @param userName
   * @param applicationName
   * @param resourceHostName
   * @param limit
   * @param offset
   */
  void getExperimentStatistics( ::apache::airavata::model::experiment::ExperimentStatistics& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const int64_t fromTime, const int64_t toTime, const std::string& userName, const std::string& applicationName, const std::string& resourceHostName, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("getExperimentStatistics\n");
  }

  /**
   * 
   * Get All Experiments of the Project
   * Get Experiments within project with pagination. Results will be sorted based on creation time DESC.
   * 
   * @param projectId
   *       Uniqie 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
   */
  void getExperimentsInProject(std::vector< ::apache::airavata::model::experiment::ExperimentModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& projectId, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("getExperimentsInProject\n");
  }

  /**
   * 
   * Get All Experiments of the User
   * 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 end 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
   */
  void getUserExperiments(std::vector< ::apache::airavata::model::experiment::ExperimentModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const std::string& userName, const int32_t limit, const int32_t offset) {
    // Your implementation goes here
    printf("getUserExperiments\n");
  }

  /**
   *   *
   *   * Create New Experiment
   *   * Create an experiment for the specified user belonging to the gateway. The gateway identity is not explicitly passed
   *   *   but inferred from the sshKeyAuthentication 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 gatewayId
   *   *    The unique ID of the gateway where the experiment is been created.
   *   *
   *   * @param ExperimentModel
   *   *    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
   */
  void createExperiment(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::experiment::ExperimentModel& experiment) {
    // Your implementation goes here
    printf("createExperiment\n");
  }

  /**
   * 
   * Delete an Experiment
   * If the experiment is not already launched experiment can be deleted.
   * 
   * @param authzToken
   * 
   * @param experiementId
   *     Experiment ID of the experimnet you want to delete.
   * 
   * @return boolean
   *     Identifier for the success or failure of the deletion operation.
   * 
   * 
   * 
   * @param authzToken
   * @param experimentId
   */
  bool deleteExperiment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& experimentId) {
    // Your implementation goes here
    printf("deleteExperiment\n");
  }

  /**
   *   *
   *   * Get Experiment
   *   * Fetch previously created experiment metadata.
   *   *
   *   * @param airavataExperimentId
   *   *    The unique identifier of the requested experiment. This ID is returned during the create experiment step.
   *   *
   *   * @return ExperimentModel
   *   *   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
   */
  void getExperiment( ::apache::airavata::model::experiment::ExperimentModel& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getExperiment\n");
  }

  /**
   *   *
   *   * Get Experiment by an admin user
   *   *
   *   * Used by an admin user to fetch previously created experiment metadata.
   *   *
   *   * @param airavataExperimentId
   *   *    The unique identifier of the requested experiment. This ID is returned during the create experiment step.
   *   *
   *   * @return ExperimentModel
   *   *   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
   */
  void getExperimentByAdmin( ::apache::airavata::model::experiment::ExperimentModel& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getExperimentByAdmin\n");
  }

  /**
   * 
   * Get Complete Experiment Details
   * 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 ExperimentModel
   *   This method will return the previously stored experiment metadata including application input parameters, computational resource scheduling
   *   information, special input output handling and additional quality of service parameters.
   * 
   * @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
   */
  void getDetailedExperimentTree( ::apache::airavata::model::experiment::ExperimentModel& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getDetailedExperimentTree\n");
  }

  /**
   * 
   * Update a Previously Created Experiment
   * Configure the 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 ExperimentModel
   *    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
   */
  void updateExperiment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const  ::apache::airavata::model::experiment::ExperimentModel& experiment) {
    // Your implementation goes here
    printf("updateExperiment\n");
  }

  void updateExperimentConfiguration(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const  ::apache::airavata::model::experiment::UserConfigurationDataModel& userConfiguration) {
    // Your implementation goes here
    printf("updateExperimentConfiguration\n");
  }

  void updateResourceScheduleing(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const  ::apache::airavata::model::scheduling::ComputationalResourceSchedulingModel& resourceScheduling) {
    // Your implementation goes here
    printf("updateResourceScheduleing\n");
  }

  /**
   *  *
   *  * Validate experiment configuration.
   *  * A true in general indicates, the experiment is ready to be launched.
   *  *
   *  * @param airavataExperimentId
   *  *    Unique identifier of the experiment (Experimnent ID) of the experiment which need to be validated.
   *  *
   *  * @return boolean
   *  *      Identifier for the success or failure of the validation operation.
   *  *
   * *
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  bool validateExperiment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("validateExperiment\n");
  }

  /**
   * 
   * Launch a Previously Created & 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.
   * 
   * @gatewayId
   *    ID of the gateway which will launch the 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
   */
  void launchExperiment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("launchExperiment\n");
  }

  /**
   * 
   * Get Experiment Status
   * 
   * Obtain the status of an experiment by providing the Experiment Id
   * 
   * @param authzToken
   * 
   * @param airavataExperimentId
   *     Experiment ID of the experimnet you require the status.
   * 
   * @return ExperimentStatus
   *     ExperimentStatus model with the current status will be returned.
   * 
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  void getExperimentStatus( ::apache::airavata::model::status::ExperimentStatus& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getExperimentStatus\n");
  }

  /**
   * 
   * Get Experiment Outputs
   * This method to be used when need to obtain final outputs of a certain Experiment
   * 
   * @param authzToken
   * 
   * @param airavataExperimentId
   *     Experiment ID of the experimnet you need the outputs.
   * 
   * @return list
   *     List of experiment outputs will be returned. They will be returned as a list of OutputDataObjectType for the experiment.
   * 
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  void getExperimentOutputs(std::vector< ::apache::airavata::model::application::io::OutputDataObjectType> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getExperimentOutputs\n");
  }

  /**
   * 
   * Get Intermediate Experiment Outputs
   * This method to be used when need to obtain intermediate outputs of a certain Experiment
   * 
   * @param authzToken
   * 
   * @param airavataExperimentId
   *     Experiment ID of the experimnet you need intermediate outputs.
   * 
   * @return list
   *     List of intermediate experiment outputs will be returned. They will be returned as a list of OutputDataObjectType for the experiment.
   * 
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  void getIntermediateOutputs(std::vector< ::apache::airavata::model::application::io::OutputDataObjectType> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getIntermediateOutputs\n");
  }

  /**
   * Request fetching of output files for an experiment that is still executing.
   * This method results in a new Process being created for the Experiment with
   * tasks for fetching each output file.
   * 
   * @param authzToken
   * 
   * @param airavataExperimentId
   *     Experiment ID of the experiment
   * 
   * @param outputNames
   *     List of names of the experiment's outputs to fetch.
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   * @param outputNames
   */
  void fetchIntermediateOutputs(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const std::vector<std::string> & outputNames) {
    // Your implementation goes here
    printf("fetchIntermediateOutputs\n");
  }

  /**
   * Get the status of the most recent intermediate output fetching process for the given output names.
   * 
   * @param authzToken
   * 
   * @param airavataExperimentId
   *     Experiment ID of the experiment
   * 
   * @param outputNames
   *     List of names of the experiment's outputs to fetch.
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   * @param outputNames
   */
  void getIntermediateOutputProcessStatus( ::apache::airavata::model::status::ProcessStatus& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const std::vector<std::string> & outputNames) {
    // Your implementation goes here
    printf("getIntermediateOutputProcessStatus\n");
  }

  /**
   * 
   * Get Job Statuses for an Experiment
   * This method to be used when need to get the job status of an Experiment. An experiment may have one or many jobs; there for one or many job statuses may turnup
   * 
   * @param authzToken
   * 
   * @param experiementId
   *     Experiment ID of the experimnet you need the job statuses.
   * 
   * @return JobStatus
   *     Job status (string) for all all the existing jobs for the experiment will be returned in the form of a map
   * 
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  void getJobStatuses(std::map<std::string,  ::apache::airavata::model::status::JobStatus> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getJobStatuses\n");
  }

  /**
   * 
   * Get Job Details for all the jobs within an Experiment.
   * This method to be used when need to get the job details for one or many jobs of an Experiment.
   * 
   * @param authzToken
   * 
   * @param experiementId
   *     Experiment ID of the experimnet you need job details.
   * 
   * @return list of JobDetails
   *     Job details.
   * 
   * 
   * 
   * @param authzToken
   * @param airavataExperimentId
   */
  void getJobDetails(std::vector< ::apache::airavata::model::job::JobModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId) {
    // Your implementation goes here
    printf("getJobDetails\n");
  }

  /**
   * 
   * Clone an Existing Experiment
   * Existing specified experiment is cloned and a new name is provided. 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.
   * @param newExperimentProjectId
   *    The project in which to create the cloned experiment. This is optional and if null the experiment will be created
   *      in the same project as the existing experiment.
   * 
   * @return
   *   The server-side generated.airavata.registry.core.experiment.globally unique identifier (Experiment ID) 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
   * @param newExperimentProjectId
   */
  void cloneExperiment(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& existingExperimentID, const std::string& newExperimentName, const std::string& newExperimentProjectId) {
    // Your implementation goes here
    printf("cloneExperiment\n");
  }

  /**
   * 
   * Clone an Existing Experiment by an admin user
   * Existing specified experiment is cloned and a new name is provided. 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.
   * @param newExperimentProjectId
   *    The project in which to create the cloned experiment. This is optional and if null the experiment will be created
   *      in the same project as the existing experiment.
   * 
   * @return
   *   The server-side generated.airavata.registry.core.experiment.globally unique identifier (Experiment ID) 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
   * @param newExperimentProjectId
   */
  void cloneExperimentByAdmin(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& existingExperimentID, const std::string& newExperimentName, const std::string& newExperimentProjectId) {
    // Your implementation goes here
    printf("cloneExperimentByAdmin\n");
  }

  /**
   * 
   * Terminate a running Experiment.
   * 
   * @gatewayId
   *    ID of the gateway which will terminate the running Experiment.
   * 
   * @param airavataExperimentId
   *    The identifier of the experiment required termination. This ID is returned during the create experiment step.
   * 
   * @return status
   *   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
   */
  void terminateExperiment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& airavataExperimentId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("terminateExperiment\n");
  }

  /**
   * 
   * Register a Application Module.
   * 
   * @gatewayId
   *    ID of the gateway which is registering the new Application Module.
   * 
   * @param applicationModule
   *    Application Module Object created from the datamodel.
   * 
   * @return appModuleId
   *   Returns the server-side generated airavata appModule globally unique identifier.
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param applicationModule
   */
  void registerApplicationModule(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::appcatalog::appdeployment::ApplicationModule& applicationModule) {
    // Your implementation goes here
    printf("registerApplicationModule\n");
  }

  /**
   * 
   * Fetch a Application Module.
   * 
   * @param appModuleId
   *   The unique identifier of the application module required
   * 
   * @return applicationModule
   *   Returns an Application Module Object.
   * 
   * 
   * @param authzToken
   * @param appModuleId
   */
  void getApplicationModule( ::apache::airavata::model::appcatalog::appdeployment::ApplicationModule& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appModuleId) {
    // Your implementation goes here
    printf("getApplicationModule\n");
  }

  /**
   * 
   * 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
   */
  bool updateApplicationModule(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appModuleId, const  ::apache::airavata::model::appcatalog::appdeployment::ApplicationModule& applicationModule) {
    // Your implementation goes here
    printf("updateApplicationModule\n");
  }

  /**
   * 
   * Fetch all Application Module Descriptions.
   * 
   * @param gatewayId
   *    ID of the gateway which need to list all available application deployment documentation.
   * 
   * @return list
   *    Returns the list of all Application Module Objects.
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getAllAppModules(std::vector< ::apache::airavata::model::appcatalog::appdeployment::ApplicationModule> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllAppModules\n");
  }

  /**
   * 
   * Fetch all accessible Application Module Descriptions.
   * 
   * @param gatewayId
   *    ID of the gateway which need to list all accessible application deployment documentation.
   * 
   * @return list
   *    Returns the list of all Application Module Objects that are accessible to the user.
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getAccessibleAppModules(std::vector< ::apache::airavata::model::appcatalog::appdeployment::ApplicationModule> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAccessibleAppModules\n");
  }

  /**
   * 
   * Delete an Application Module.
   * 
   * @param appModuleId
   *   The identifier of the Application Module to be deleted.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param appModuleId
   */
  bool deleteApplicationModule(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appModuleId) {
    // Your implementation goes here
    printf("deleteApplicationModule\n");
  }

  /**
   * 
   * Register an Application Deployment.
   * 
   * @param gatewayId
   *    ID of the gateway which is registering the new Application Deployment.
   * 
   * @param applicationDeployment
   *    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
   */
  void registerApplicationDeployment(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription& applicationDeployment) {
    // Your implementation goes here
    printf("registerApplicationDeployment\n");
  }

  /**
   * 
   * Fetch a Application Deployment.
   * 
   * @param appDeploymentId
   *   The identifier for the requested application module
   * 
   * @return applicationDeployment
   *   Returns a application Deployment Object.
   * 
   * 
   * @param authzToken
   * @param appDeploymentId
   */
  void getApplicationDeployment( ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appDeploymentId) {
    // Your implementation goes here
    printf("getApplicationDeployment\n");
  }

  /**
   * 
   * Update an Application Deployment.
   * 
   * @param appDeploymentId
   *   The identifier of 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
   */
  bool updateApplicationDeployment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appDeploymentId, const  ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription& applicationDeployment) {
    // Your implementation goes here
    printf("updateApplicationDeployment\n");
  }

  /**
   * 
   * Delete an Application Deployment.
   * 
   * @param appDeploymentId
   *   The unique identifier of application deployment to be deleted.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param appDeploymentId
   */
  bool deleteApplicationDeployment(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appDeploymentId) {
    // Your implementation goes here
    printf("deleteApplicationDeployment\n");
  }

  /**
   * 
   * Fetch all Application Deployment Descriptions.
   * 
   * @param gatewayId
   *    ID of the gateway which need to list all available application deployment documentation.
   * 
   * @return list<applicationDeployment.
   *    Returns the list of all application Deployment Objects.
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getAllApplicationDeployments(std::vector< ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllApplicationDeployments\n");
  }

  /**
   * 
   * Fetch all accessible Application Deployment Descriptions.
   * 
   * @param gatewayId
   *    ID of the gateway which need to list all accessible application deployment documentation.
   * @param permissionType
   *    ResourcePermissionType to check for this user
   * 
   * @return list<applicationDeployment.
   *    Returns the list of all application Deployment Objects that are accessible to the user.
   * 
   * 
   * @param authzToken
   * @param gatewayId
   * @param permissionType
   */
  void getAccessibleApplicationDeployments(std::vector< ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("getAccessibleApplicationDeployments\n");
  }

  /**
   * 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
   */
  void getAppModuleDeployedResources(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appModuleId) {
    // Your implementation goes here
    printf("getAppModuleDeployedResources\n");
  }

  /**
   * Fetch a list of Application Deployments that this user can use for executing the given Application Module using the given Group Resource Profile.
   * The user must have at least READ access to the Group Resource Profile.
   * 
   * @param appModuleId
   *    The identifier for the Application Module
   * 
   * @param groupResourceProfileId
   *    The identifier for the Group Resource Profile
   * 
   * @return list<ApplicationDeploymentDescription>
   *    Returns a list of Application Deployments
   * 
   * @param authzToken
   * @param appModuleId
   * @param groupResourceProfileId
   */
  void getApplicationDeploymentsForAppModuleAndGroupResourceProfile(std::vector< ::apache::airavata::model::appcatalog::appdeployment::ApplicationDeploymentDescription> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appModuleId, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getApplicationDeploymentsForAppModuleAndGroupResourceProfile\n");
  }

  /**
   * 
   * Register a Application Interface.
   * 
   * @param applicationInterface
   *    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
   */
  void registerApplicationInterface(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId, const  ::apache::airavata::model::appcatalog::appinterface::ApplicationInterfaceDescription& applicationInterface) {
    // Your implementation goes here
    printf("registerApplicationInterface\n");
  }

  /**
   * 
   * Clone an Application Interface.
   * 
   * @gatewayId
   *    The identifier for the gateway profile to be requested
   * 
   * @param existingAppInterfaceID
   *    Identifier of the existing Application interface you wich to clone.
   * 
   * @param newApplicationName
   *    Name for the new application interface.
   * 
   * @return appInterfaceId
   *    Returns a server-side generated globally unique identifier for the newly cloned application interface.
   * 
   * 
   * @param authzToken
   * @param existingAppInterfaceID
   * @param newApplicationName
   * @param gatewayId
   */
  void cloneApplicationInterface(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& existingAppInterfaceID, const std::string& newApplicationName, const std::string& gatewayId) {
    // Your implementation goes here
    printf("cloneApplicationInterface\n");
  }

  /**
   * 
   * Fetch an Application Interface.
   * 
   * @param appInterfaceId
   *   The identifier for the requested application interface.
   * 
   * @return applicationInterface
   *   Returns an application Interface Object.
   * 
   * 
   * @param authzToken
   * @param appInterfaceId
   */
  void getApplicationInterface( ::apache::airavata::model::appcatalog::appinterface::ApplicationInterfaceDescription& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId) {
    // Your implementation goes here
    printf("getApplicationInterface\n");
  }

  /**
   * 
   * Update a Application Interface.
   * 
   * @param appInterfaceId
   *   The identifier of 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
   */
  bool updateApplicationInterface(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId, const  ::apache::airavata::model::appcatalog::appinterface::ApplicationInterfaceDescription& applicationInterface) {
    // Your implementation goes here
    printf("updateApplicationInterface\n");
  }

  /**
   * 
   * Delete an 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
   */
  bool deleteApplicationInterface(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId) {
    // Your implementation goes here
    printf("deleteApplicationInterface\n");
  }

  /**
   * 
   * 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
   */
  void getAllApplicationInterfaceNames(std::map<std::string, std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllApplicationInterfaceNames\n");
  }

  /**
   * 
   * Fetch all Application Interface documents.
   * 
   * 
   * @return map<applicationId, applicationInterfaceNames>
   *   Returns a list of application interfaces documents (Application Interface ID, name, description, Inputs and Outputs objects).
   * 
   * 
   * @param authzToken
   * @param gatewayId
   */
  void getAllApplicationInterfaces(std::vector< ::apache::airavata::model::appcatalog::appinterface::ApplicationInterfaceDescription> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getAllApplicationInterfaces\n");
  }

  /**
   * 
   * Fetch the list of Application Inputs.
   * 
   * @param appInterfaceId
   *   The identifier of the application interface which need inputs to be fetched.
   * 
   * @return list<application_interface_model.InputDataObjectType>
   *   Returns a list of application inputs.
   * 
   * 
   * @param authzToken
   * @param appInterfaceId
   */
  void getApplicationInputs(std::vector< ::apache::airavata::model::application::io::InputDataObjectType> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId) {
    // Your implementation goes here
    printf("getApplicationInputs\n");
  }

  /**
   * 
   * Fetch list of Application Outputs.
   * 
   * @param appInterfaceId
   *   The identifier of the application interface which need outputs to be fetched.
   * 
   * @return list<application_interface_model.OutputDataObjectType>
   *   Returns a list of application outputs.
   * 
   * 
   * @param authzToken
   * @param appInterfaceId
   */
  void getApplicationOutputs(std::vector< ::apache::airavata::model::application::io::OutputDataObjectType> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId) {
    // Your implementation goes here
    printf("getApplicationOutputs\n");
  }

  /**
   * 
   * 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
   */
  void getAvailableAppInterfaceComputeResources(std::map<std::string, std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& appInterfaceId) {
    // Your implementation goes here
    printf("getAvailableAppInterfaceComputeResources\n");
  }

  /**
   * 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
   */
  void registerComputeResource(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::computeresource::ComputeResourceDescription& computeResourceDescription) {
    // Your implementation goes here
    printf("registerComputeResource\n");
  }

  /**
   * 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
   */
  void getComputeResource( ::apache::airavata::model::appcatalog::computeresource::ComputeResourceDescription& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId) {
    // Your implementation goes here
    printf("getComputeResource\n");
  }

  /**
   * 
   * 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
   */
  void getAllComputeResourceNames(std::map<std::string, std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getAllComputeResourceNames\n");
  }

  /**
   * 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
   */
  bool updateComputeResource(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const  ::apache::airavata::model::appcatalog::computeresource::ComputeResourceDescription& computeResourceDescription) {
    // Your implementation goes here
    printf("updateComputeResource\n");
  }

  /**
   * 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
   */
  bool deleteComputeResource(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId) {
    // Your implementation goes here
    printf("deleteComputeResource\n");
  }

  /**
   * Register a Storage Resource.
   * 
   * @param storageResourceDescription
   *    Storge Resource Object created from the datamodel.
   * 
   * @return storageResourceId
   *   Returns a server-side generated airavata storage resource globally unique identifier.
   * 
   * 
   * @param authzToken
   * @param storageResourceDescription
   */
  void registerStorageResource(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::storageresource::StorageResourceDescription& storageResourceDescription) {
    // Your implementation goes here
    printf("registerStorageResource\n");
  }

  /**
   * Fetch the given Storage Resource.
   * 
   * @param storageResourceId
   *   The identifier for the requested storage resource
   * 
   * @return storageResourceDescription
   *    Storage Resource Object created from the datamodel..
   * 
   * 
   * @param authzToken
   * @param storageResourceId
   */
  void getStorageResource( ::apache::airavata::model::appcatalog::storageresource::StorageResourceDescription& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& storageResourceId) {
    // Your implementation goes here
    printf("getStorageResource\n");
  }

  /**
   * Fetch all registered Storage Resources.
   * 
   * @return A map of registered compute resource id's and thier corresponding hostnames.
   *    Compute Resource Object created from the datamodel..
   * 
   * 
   * @param authzToken
   */
  void getAllStorageResourceNames(std::map<std::string, std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getAllStorageResourceNames\n");
  }

  /**
   * Update a Storage Resource.
   * 
   * @param storageResourceId
   *   The identifier for the requested compute resource to be updated.
   * 
   * @param storageResourceDescription
   *    Storage Resource Object created from the datamodel.
   * 
   * @return status
   *   Returns a success/failure of the update.
   * 
   * 
   * @param authzToken
   * @param storageResourceId
   * @param storageResourceDescription
   */
  bool updateStorageResource(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& storageResourceId, const  ::apache::airavata::model::appcatalog::storageresource::StorageResourceDescription& storageResourceDescription) {
    // Your implementation goes here
    printf("updateStorageResource\n");
  }

  /**
   * Delete a Storage Resource.
   * 
   * @param storageResourceId
   *   The identifier of the requested compute resource to be deleted.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param storageResourceId
   */
  bool deleteStorageResource(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& storageResourceId) {
    // Your implementation goes here
    printf("deleteStorageResource\n");
  }

  /**
   * 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
   */
  void addLocalSubmissionDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const int32_t priorityOrder, const  ::apache::airavata::model::appcatalog::computeresource::LOCALSubmission& localSubmission) {
    // Your implementation goes here
    printf("addLocalSubmissionDetails\n");
  }

  /**
   * 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
   */
  bool updateLocalSubmissionDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionInterfaceId, const  ::apache::airavata::model::appcatalog::computeresource::LOCALSubmission& localSubmission) {
    // Your implementation goes here
    printf("updateLocalSubmissionDetails\n");
  }

  /**
   * This method returns localJobSubmission object
   * @param jobSubmissionInterfaceId
   *   The identifier of the JobSubmission Interface to be retrieved.
   *  @return LOCALSubmission instance
   * 
   * 
   * @param authzToken
   * @param jobSubmissionId
   */
  void getLocalJobSubmission( ::apache::airavata::model::appcatalog::computeresource::LOCALSubmission& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionId) {
    // Your implementation goes here
    printf("getLocalJobSubmission\n");
  }

  /**
   * 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
   */
  void addSSHJobSubmissionDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const int32_t priorityOrder, const  ::apache::airavata::model::appcatalog::computeresource::SSHJobSubmission& sshJobSubmission) {
    // Your implementation goes here
    printf("addSSHJobSubmissionDetails\n");
  }

  /**
   * 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
   */
  void addSSHForkJobSubmissionDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const int32_t priorityOrder, const  ::apache::airavata::model::appcatalog::computeresource::SSHJobSubmission& sshJobSubmission) {
    // Your implementation goes here
    printf("addSSHForkJobSubmissionDetails\n");
  }

  /**
   * This method returns SSHJobSubmission object
   * @param jobSubmissionInterfaceId
   *   The identifier of the JobSubmission Interface to be retrieved.
   *  @return SSHJobSubmission instance
   * 
   * 
   * @param authzToken
   * @param jobSubmissionId
   */
  void getSSHJobSubmission( ::apache::airavata::model::appcatalog::computeresource::SSHJobSubmission& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionId) {
    // Your implementation goes here
    printf("getSSHJobSubmission\n");
  }

  /**
   * 
   * 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
   */
  void addUNICOREJobSubmissionDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const int32_t priorityOrder, const  ::apache::airavata::model::appcatalog::computeresource::UnicoreJobSubmission& unicoreJobSubmission) {
    // Your implementation goes here
    printf("addUNICOREJobSubmissionDetails\n");
  }

  /**
   *   *
   *   * This method returns UnicoreJobSubmission object
   *   *
   *   * @param jobSubmissionInterfaceId
   *   *   The identifier of the JobSubmission Interface to be retrieved.
   *   *  @return UnicoreJobSubmission instance
   *   *
   * *
   * 
   * @param authzToken
   * @param jobSubmissionId
   */
  void getUnicoreJobSubmission( ::apache::airavata::model::appcatalog::computeresource::UnicoreJobSubmission& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionId) {
    // Your implementation goes here
    printf("getUnicoreJobSubmission\n");
  }

  /**
   *    *
   *    * 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
   */
  void addCloudJobSubmissionDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const int32_t priorityOrder, const  ::apache::airavata::model::appcatalog::computeresource::CloudJobSubmission& cloudSubmission) {
    // Your implementation goes here
    printf("addCloudJobSubmissionDetails\n");
  }

  /**
   *    *
   *    * This method returns cloudJobSubmission object
   *    * @param jobSubmissionInterfaceI
   *        *   The identifier of the JobSubmission Interface to be retrieved.
   *    *  @return CloudJobSubmission instance
   * *
   * 
   * @param authzToken
   * @param jobSubmissionId
   */
  void getCloudJobSubmission( ::apache::airavata::model::appcatalog::computeresource::CloudJobSubmission& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionId) {
    // Your implementation goes here
    printf("getCloudJobSubmission\n");
  }

  /**
   * 
   * 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 update.
   * 
   * 
   * @param authzToken
   * @param jobSubmissionInterfaceId
   * @param sshJobSubmission
   */
  bool updateSSHJobSubmissionDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionInterfaceId, const  ::apache::airavata::model::appcatalog::computeresource::SSHJobSubmission& sshJobSubmission) {
    // Your implementation goes here
    printf("updateSSHJobSubmissionDetails\n");
  }

  /**
   * 
   * 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 update.
   * 
   * 
   * @param authzToken
   * @param jobSubmissionInterfaceId
   * @param sshJobSubmission
   */
  bool updateCloudJobSubmissionDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionInterfaceId, const  ::apache::airavata::model::appcatalog::computeresource::CloudJobSubmission& sshJobSubmission) {
    // Your implementation goes here
    printf("updateCloudJobSubmissionDetails\n");
  }

  /**
   * 
   * Update the UNIOCRE Job Submission details
   * 
   * @param jobSubmissionInterfaceId
   *   The identifier of the JobSubmission Interface to be updated.
   * 
   * @param UnicoreJobSubmission
   *   The UnicoreJobSubmission object to be updated.
   * 
   * @return status
   *   Returns a success/failure of the update.
   * 
   * 
   * 
   * @param authzToken
   * @param jobSubmissionInterfaceId
   * @param unicoreJobSubmission
   */
  bool updateUnicoreJobSubmissionDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionInterfaceId, const  ::apache::airavata::model::appcatalog::computeresource::UnicoreJobSubmission& unicoreJobSubmission) {
    // Your implementation goes here
    printf("updateUnicoreJobSubmissionDetails\n");
  }

  /**
   * 
   * Add a Local data movement details to a compute resource
   *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
   * 
   * @param productUri
   *   The identifier of the compute resource to which JobSubmission protocol to be added
   * 
   * @param DMType
   *   DMType object to be added to the resource.
   * 
   * @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 productUri
   * @param dataMoveType
   * @param priorityOrder
   * @param localDataMovement
   */
  void addLocalDataMovementDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri, const  ::apache::airavata::model::data::movement::DMType::type dataMoveType, const int32_t priorityOrder, const  ::apache::airavata::model::data::movement::LOCALDataMovement& localDataMovement) {
    // Your implementation goes here
    printf("addLocalDataMovementDetails\n");
  }

  /**
   * 
   * 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
   */
  bool updateLocalDataMovementDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementInterfaceId, const  ::apache::airavata::model::data::movement::LOCALDataMovement& localDataMovement) {
    // Your implementation goes here
    printf("updateLocalDataMovementDetails\n");
  }

  /**
   * 
   * This method returns local datamovement object.
   * 
   * @param dataMovementId
   *   The identifier of the datamovement Interface to be retrieved.
   * 
   *  @return LOCALDataMovement instance
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementId
   */
  void getLocalDataMovement( ::apache::airavata::model::data::movement::LOCALDataMovement& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementId) {
    // Your implementation goes here
    printf("getLocalDataMovement\n");
  }

  /**
   * 
   * Add a SCP data movement details to a compute resource
   *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
   * 
   * @param productUri
   *   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 productUri
   * @param dataMoveType
   * @param priorityOrder
   * @param scpDataMovement
   */
  void addSCPDataMovementDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri, const  ::apache::airavata::model::data::movement::DMType::type dataMoveType, const int32_t priorityOrder, const  ::apache::airavata::model::data::movement::SCPDataMovement& scpDataMovement) {
    // Your implementation goes here
    printf("addSCPDataMovementDetails\n");
  }

  /**
   * 
   * 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
   */
  bool updateSCPDataMovementDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementInterfaceId, const  ::apache::airavata::model::data::movement::SCPDataMovement& scpDataMovement) {
    // Your implementation goes here
    printf("updateSCPDataMovementDetails\n");
  }

  /**
   * This method returns SCP datamovement object
   * 
   * @param dataMovementId
   *   The identifier of the datamovement Interface to be retrieved.
   * 
   * @return SCPDataMovement instance
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementId
   */
  void getSCPDataMovement( ::apache::airavata::model::data::movement::SCPDataMovement& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementId) {
    // Your implementation goes here
    printf("getSCPDataMovement\n");
  }

  /**
   * 
   * Add a UNICORE data movement details to a compute resource
   *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
   * 
   * @param productUri
   *   The identifier of the compute resource to which data movement 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 UnicoreDataMovement
   *   The UnicoreDataMovement object to be added to the resource.
   * 
   * @return status
   *   Returns the unique data movement id.
   * 
   * 
   * @param authzToken
   * @param productUri
   * @param dataMoveType
   * @param priorityOrder
   * @param unicoreDataMovement
   */
  void addUnicoreDataMovementDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri, const  ::apache::airavata::model::data::movement::DMType::type dataMoveType, const int32_t priorityOrder, const  ::apache::airavata::model::data::movement::UnicoreDataMovement& unicoreDataMovement) {
    // Your implementation goes here
    printf("addUnicoreDataMovementDetails\n");
  }

  /**
   * 
   * Update a selected UNICORE 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 UnicoreDataMovement
   *   The UnicoreDataMovement object to be updated.
   * 
   * @return status
   *   Returns a success/failure of the update.
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementInterfaceId
   * @param unicoreDataMovement
   */
  bool updateUnicoreDataMovementDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementInterfaceId, const  ::apache::airavata::model::data::movement::UnicoreDataMovement& unicoreDataMovement) {
    // Your implementation goes here
    printf("updateUnicoreDataMovementDetails\n");
  }

  /**
   * 
   * This method returns UNICORE datamovement object
   * 
   * @param dataMovementId
   *   The identifier of the datamovement Interface to be retrieved.
   * 
   * @return UnicoreDataMovement instance
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementId
   */
  void getUnicoreDataMovement( ::apache::airavata::model::data::movement::UnicoreDataMovement& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementId) {
    // Your implementation goes here
    printf("getUnicoreDataMovement\n");
  }

  /**
   * 
   * Add a GridFTP data movement details to a compute resource
   *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
   * 
   * @param productUri
   *   The identifier of the compute resource to which dataMovement protocol to be added
   * 
   * @param DMType
   *    The DMType object to be added to the resource.
   * 
   * @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 data movement id.
   * 
   * 
   * 
   * @param authzToken
   * @param productUri
   * @param dataMoveType
   * @param priorityOrder
   * @param gridFTPDataMovement
   */
  void addGridFTPDataMovementDetails(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri, const  ::apache::airavata::model::data::movement::DMType::type dataMoveType, const int32_t priorityOrder, const  ::apache::airavata::model::data::movement::GridFTPDataMovement& gridFTPDataMovement) {
    // Your implementation goes here
    printf("addGridFTPDataMovementDetails\n");
  }

  /**
   * 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 boolean
   *   Returns a success/failure of the update.
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementInterfaceId
   * @param gridFTPDataMovement
   */
  bool updateGridFTPDataMovementDetails(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementInterfaceId, const  ::apache::airavata::model::data::movement::GridFTPDataMovement& gridFTPDataMovement) {
    // Your implementation goes here
    printf("updateGridFTPDataMovementDetails\n");
  }

  /**
   * This method returns GridFTP datamovement object
   * 
   * @param dataMovementId
   *   The identifier of the datamovement Interface to be retrieved.
   * 
   *  @return GridFTPDataMovement instance
   * 
   * 
   * 
   * @param authzToken
   * @param dataMovementId
   */
  void getGridFTPDataMovement( ::apache::airavata::model::data::movement::GridFTPDataMovement& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementId) {
    // Your implementation goes here
    printf("getGridFTPDataMovement\n");
  }

  /**
   * 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
   */
  bool changeJobSubmissionPriority(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& jobSubmissionInterfaceId, const int32_t newPriorityOrder) {
    // Your implementation goes here
    printf("changeJobSubmissionPriority\n");
  }

  /**
   * 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
   */
  bool changeDataMovementPriority(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataMovementInterfaceId, const int32_t newPriorityOrder) {
    // Your implementation goes here
    printf("changeDataMovementPriority\n");
  }

  /**
   * 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
   */
  bool changeJobSubmissionPriorities(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::map<std::string, int32_t> & jobSubmissionPriorityMap) {
    // Your implementation goes here
    printf("changeJobSubmissionPriorities\n");
  }

  /**
   * 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
   */
  bool changeDataMovementPriorities(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::map<std::string, int32_t> & dataMovementPriorityMap) {
    // Your implementation goes here
    printf("changeDataMovementPriorities\n");
  }

  /**
   * 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
   */
  bool deleteJobSubmissionInterface(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& jobSubmissionInterfaceId) {
    // Your implementation goes here
    printf("deleteJobSubmissionInterface\n");
  }

  /**
   * 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 productUri
   * @param dataMovementInterfaceId
   * @param dataMoveType
   */
  bool deleteDataMovementInterface(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri, const std::string& dataMovementInterfaceId, const  ::apache::airavata::model::data::movement::DMType::type dataMoveType) {
    // Your implementation goes here
    printf("deleteDataMovementInterface\n");
  }

  void registerResourceJobManager(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::computeresource::ResourceJobManager& resourceJobManager) {
    // Your implementation goes here
    printf("registerResourceJobManager\n");
  }

  bool updateResourceJobManager(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceJobManagerId, const  ::apache::airavata::model::appcatalog::computeresource::ResourceJobManager& updatedResourceJobManager) {
    // Your implementation goes here
    printf("updateResourceJobManager\n");
  }

  void getResourceJobManager( ::apache::airavata::model::appcatalog::computeresource::ResourceJobManager& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceJobManagerId) {
    // Your implementation goes here
    printf("getResourceJobManager\n");
  }

  bool deleteResourceJobManager(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceJobManagerId) {
    // Your implementation goes here
    printf("deleteResourceJobManager\n");
  }

  /**
   * Delete a Compute Resource Queue
   * 
   * @param computeResourceId
   *   The identifier of the compute resource which has the queue to be deleted
   * 
   * @param queueName
   *   Name of the queue need to be deleted. Name is the uniqueue identifier for the queue within a compute resource
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * 
   * @param authzToken
   * @param computeResourceId
   * @param queueName
   */
  bool deleteBatchQueue(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& queueName) {
    // Your implementation goes here
    printf("deleteBatchQueue\n");
  }

  /**
   * 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
   */
  void registerGatewayResourceProfile(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::gatewayprofile::GatewayResourceProfile& gatewayResourceProfile) {
    // Your implementation goes here
    printf("registerGatewayResourceProfile\n");
  }

  /**
   * 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
   */
  void getGatewayResourceProfile( ::apache::airavata::model::appcatalog::gatewayprofile::GatewayResourceProfile& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getGatewayResourceProfile\n");
  }

  /**
   * 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
   */
  bool updateGatewayResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const  ::apache::airavata::model::appcatalog::gatewayprofile::GatewayResourceProfile& gatewayResourceProfile) {
    // Your implementation goes here
    printf("updateGatewayResourceProfile\n");
  }

  /**
   * 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
   */
  bool deleteGatewayResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID) {
    // Your implementation goes here
    printf("deleteGatewayResourceProfile\n");
  }

  /**
   * 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
   */
  bool addGatewayComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& computeResourceId, const  ::apache::airavata::model::appcatalog::gatewayprofile::ComputeResourcePreference& computeResourcePreference) {
    // Your implementation goes here
    printf("addGatewayComputeResourcePreference\n");
  }

  /**
   * Add a Storage Resource Preference to a registered gateway profile.
   * 
   * @param gatewayID
   *   The identifier of the gateway profile to be added.
   * 
   * @param storageResourceId
   *   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 storageResourceId
   * @param storagePreference
   */
  bool addGatewayStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& storageResourceId, const  ::apache::airavata::model::appcatalog::gatewayprofile::StoragePreference& storagePreference) {
    // Your implementation goes here
    printf("addGatewayStoragePreference\n");
  }

  /**
   * 
   * 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
   */
  void getGatewayComputeResourcePreference( ::apache::airavata::model::appcatalog::gatewayprofile::ComputeResourcePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& computeResourceId) {
    // Your implementation goes here
    printf("getGatewayComputeResourcePreference\n");
  }

  /**
   * 
   * Fetch a Storage Resource Preference of a registered gateway profile.
   * 
   * @param gatewayID
   *   The identifier of the gateway profile to request to fetch the particular storage resource preference.
   * 
   * @param storageResourceId
   *   Identifier of the Stprage Preference required to be fetched.
   * 
   * @return StoragePreference
   *   Returns the StoragePreference object.
   * 
   * 
   * @param authzToken
   * @param gatewayID
   * @param storageResourceId
   */
  void getGatewayStoragePreference( ::apache::airavata::model::appcatalog::gatewayprofile::StoragePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& storageResourceId) {
    // Your implementation goes here
    printf("getGatewayStoragePreference\n");
  }

  /**
   * 
   * 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
   */
  void getAllGatewayComputeResourcePreferences(std::vector< ::apache::airavata::model::appcatalog::gatewayprofile::ComputeResourcePreference> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getAllGatewayComputeResourcePreferences\n");
  }

  /**
   * Fetch all Storage Resource Preferences of a registered gateway profile.
   * 
   * @param gatewayID
   *   The identifier for the gateway profile to be requested
   * 
   * @return StoragePreference
   *   Returns the StoragePreference object.
   * 
   * 
   * @param authzToken
   * @param gatewayID
   */
  void getAllGatewayStoragePreferences(std::vector< ::apache::airavata::model::appcatalog::gatewayprofile::StoragePreference> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getAllGatewayStoragePreferences\n");
  }

  /**
   * 
   * Fetch all Gateway Profiles registered
   * 
   * @return GatewayResourceProfile
   *   Returns all the GatewayResourcePrifle list object.
   * 
   * 
   * 
   * @param authzToken
   */
  void getAllGatewayResourceProfiles(std::vector< ::apache::airavata::model::appcatalog::gatewayprofile::GatewayResourceProfile> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getAllGatewayResourceProfiles\n");
  }

  /**
   * 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
   */
  bool updateGatewayComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& computeResourceId, const  ::apache::airavata::model::appcatalog::gatewayprofile::ComputeResourcePreference& computeResourcePreference) {
    // Your implementation goes here
    printf("updateGatewayComputeResourcePreference\n");
  }

  /**
   * Update a Storage Resource Preference of a registered gateway profile.
   * 
   * @param gatewayID
   *   The identifier of the gateway profile to be updated.
   * 
   * @param storageId
   *   The Storage resource identifier of the one that you want to update
   * 
   * @param storagePreference
   *   The storagePreference object to be updated to the resource profile.
   * 
   * @return status
   *   Returns a success/failure of the updation.
   * 
   * 
   * @param authzToken
   * @param gatewayID
   * @param storageId
   * @param storagePreference
   */
  bool updateGatewayStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& storageId, const  ::apache::airavata::model::appcatalog::gatewayprofile::StoragePreference& storagePreference) {
    // Your implementation goes here
    printf("updateGatewayStoragePreference\n");
  }

  /**
   * 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
   */
  bool deleteGatewayComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& computeResourceId) {
    // Your implementation goes here
    printf("deleteGatewayComputeResourcePreference\n");
  }

  /**
   * Delete the Storage Resource Preference of a registered gateway profile.
   * 
   * @param gatewayID
   *   The identifier of the gateway profile to be deleted.
   * 
   * @param storageId
   *   ID of the storage preference you want to delete.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param gatewayID
   * @param storageId
   */
  bool deleteGatewayStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayID, const std::string& storageId) {
    // Your implementation goes here
    printf("deleteGatewayStoragePreference\n");
  }

  void getSSHAccountProvisioners(std::vector< ::apache::airavata::model::appcatalog::accountprovisioning::SSHAccountProvisioner> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getSSHAccountProvisioners\n");
  }

  /**
   * Check if user has an SSH account on the given compute resource. This
   * method will only work if the compute resource has an SSHAccountProvisioner configured for it.
   * 
   * @param authzToken
   * @param computeResourceId
   * @param userId
   */
  bool doesUserHaveSSHAccount(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& userId) {
    // Your implementation goes here
    printf("doesUserHaveSSHAccount\n");
  }

  /**
   * Check if SSH account setup is complete for this user on the given compute resource.
   * 
   * @param authzToken
   * @param computeResourceId
   * @param airavataCredStoreToken
   */
  bool isSSHSetupCompleteForUserComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& airavataCredStoreToken) {
    // Your implementation goes here
    printf("isSSHSetupCompleteForUserComputeResourcePreference\n");
  }

  /**
   * Setup and return a UserComputeResourcePreference object for this user to SSH into the given compute resource with
   * the given SSH credential. This method will only work if the compute resource has an SSHAccountProvisioner
   * configured for it. The returned UserComputeResourcePreference object is not saved; it is up to the client to
   * call addUserComputeResourcePreference to persist it.
   * 
   * @param authzToken
   * @param computeResourceId
   * @param userId
   * @param airavataCredStoreToken
   */
  void setupUserComputeResourcePreferencesForSSH( ::apache::airavata::model::appcatalog::userresourceprofile::UserComputeResourcePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& userId, const std::string& airavataCredStoreToken) {
    // Your implementation goes here
    printf("setupUserComputeResourcePreferencesForSSH\n");
  }

  /**
   * Register User Resource Profile.
   * 
   * @param UserResourceProfile
   *    User Resource Profile Object.
   *    The userId should be obtained from Airavata user profile data model and passed to register a corresponding
   *      resource profile.
   * 
   * @return status
   *   Returns a success/failure of the update.
   * 
   * 
   * @param authzToken
   * @param userResourceProfile
   */
  void registerUserResourceProfile(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserResourceProfile& userResourceProfile) {
    // Your implementation goes here
    printf("registerUserResourceProfile\n");
  }

  /**
   * Check if User Resource Profile exists.
   * 
   * @param userId
   *   The identifier for the requested user resource profile.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @return bool
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   */
  bool isUserResourceProfileExists(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID) {
    // Your implementation goes here
    printf("isUserResourceProfileExists\n");
  }

  /**
   * Fetch the given User Resource Profile.
   * 
   * @param userId
   *   The identifier for the requested user resource profile.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @return UserResourceProfile
   *    User Resource Profile Object.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   */
  void getUserResourceProfile( ::apache::airavata::model::appcatalog::userresourceprofile::UserResourceProfile& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getUserResourceProfile\n");
  }

  /**
   * Update a User Resource Profile.
   * 
   * @param userId
   *   The identifier for the requested user resource to be updated.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param UserResourceProfile
   *    User Resource Profile Object.
   * 
   * @return status
   *   Returns a success/failure of the update.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userResourceProfile
   */
  bool updateUserResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserResourceProfile& userResourceProfile) {
    // Your implementation goes here
    printf("updateUserResourceProfile\n");
  }

  /**
   * Delete the given User Resource Profile.
   * 
   * @param userId
   *   The identifier for the requested user resource to be deleted.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   */
  bool deleteUserResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID) {
    // Your implementation goes here
    printf("deleteUserResourceProfile\n");
  }

  /**
   * Add a Compute Resource Preference to a registered User profile.
   * 
   * @param userId
   *   The identifier for the User resource profile to be added.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @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 userId
   * @param gatewayID
   * @param userComputeResourceId
   * @param userComputeResourcePreference
   */
  bool addUserComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userComputeResourceId, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserComputeResourcePreference& userComputeResourcePreference) {
    // Your implementation goes here
    printf("addUserComputeResourcePreference\n");
  }

  /**
   * Add a Storage Resource Preference to a registered user resource profile.
   * 
   * @param userId
   *   The identifier of the user resource profile to be added.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param storageResourceId
   *   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 userId
   * @param gatewayID
   * @param userStorageResourceId
   * @param userStoragePreference
   */
  bool addUserStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userStorageResourceId, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserStoragePreference& userStoragePreference) {
    // Your implementation goes here
    printf("addUserStoragePreference\n");
  }

  /**
   * 
   * Fetch a Compute Resource Preference of a registered user resource profile.
   * 
   * @param userId
   *   The identifier for the user profile to be requested
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userComputeResourceId
   *   Preferences related to a particular compute resource
   * 
   * @return computeResourcePreference
   *   Returns the ComputeResourcePreference object.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userComputeResourceId
   */
  void getUserComputeResourcePreference( ::apache::airavata::model::appcatalog::userresourceprofile::UserComputeResourcePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userComputeResourceId) {
    // Your implementation goes here
    printf("getUserComputeResourcePreference\n");
  }

  /**
   * 
   * Fetch a Storage Resource Preference of a registered user resource profile.
   * 
   * @param userId
   *   The identifier of the user resource profile to request to fetch the particular storage resource preference.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userStorageResourceId
   *   Identifier of the Stprage Preference required to be fetched.
   * 
   * @return UserStoragePreference
   *   Returns the StoragePreference object.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userStorageResourceId
   */
  void getUserStoragePreference( ::apache::airavata::model::appcatalog::userresourceprofile::UserStoragePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userStorageResourceId) {
    // Your implementation goes here
    printf("getUserStoragePreference\n");
  }

  /**
   * 
   * Fetch all Compute Resource Preferences of a registered gateway profile.
   * 
   * @param userId
   *   The identifier of the user resource profile to request to fetch the particular storage resource preference.
   * 
   * @param gatewayID
   *   The identifier for the gateway profile to be requested
   * 
   * @return computeResourcePreference
   *   Returns the ComputeResourcePreference object.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   */
  void getAllUserComputeResourcePreferences(std::vector< ::apache::airavata::model::appcatalog::userresourceprofile::UserComputeResourcePreference> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getAllUserComputeResourcePreferences\n");
  }

  /**
   * Fetch all User Storage Resource Preferences of a registered user profile.
   * 
   * @param userId
   *   The identifier of the user resource profile to request to fetch the particular storage resource preference.
   * 
   * @param gatewayID
   *   The identifier for the gateway profile to be requested
   * 
   * @return StoragePreference
   *   Returns the StoragePreference object.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   */
  void getAllUserStoragePreferences(std::vector< ::apache::airavata::model::appcatalog::userresourceprofile::UserStoragePreference> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID) {
    // Your implementation goes here
    printf("getAllUserStoragePreferences\n");
  }

  /**
   * 
   * Fetch all user resources Profiles registered
   * 
   * @return UserResourceProfile
   *   Returns all the UserResourcePrifle list object.
   * 
   * 
   * 
   * @param authzToken
   */
  void getAllUserResourceProfiles(std::vector< ::apache::airavata::model::appcatalog::userresourceprofile::UserResourceProfile> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getAllUserResourceProfiles\n");
  }

  /**
   * Update a Compute Resource Preference to a registered user resource profile.
   * 
   * @param userId
   *   The identifier for the user profile to be updated.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userComputeResourceId
   *   Preferences related to a particular compute resource
   * 
   * @param userComputeResourcePreference
   *   The ComputeResourcePreference object to be updated to the resource profile.
   * 
   * @return status
   *   Returns a success/failure of the updation.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userComputeResourceId
   * @param userComputeResourcePreference
   */
  bool updateUserComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userComputeResourceId, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserComputeResourcePreference& userComputeResourcePreference) {
    // Your implementation goes here
    printf("updateUserComputeResourcePreference\n");
  }

  /**
   * Update a Storage Resource Preference of a registered user resource profile.
   * 
   * @param userId
   *   The identifier of the user resource profile to be updated.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userStorageId
   *   The Storage resource identifier of the one that you want to update
   * 
   * @param userStoragePreference
   *   The storagePreference object to be updated to the resource profile.
   * 
   * @return status
   *   Returns a success/failure of the updation.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userStorageId
   * @param userStoragePreference
   */
  bool updateUserStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userStorageId, const  ::apache::airavata::model::appcatalog::userresourceprofile::UserStoragePreference& userStoragePreference) {
    // Your implementation goes here
    printf("updateUserStoragePreference\n");
  }

  /**
   * Delete the Compute Resource Preference of a registered user resource profile.
   * 
   * @param userId
   *   The identifier for the user resource profile to be deleted.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userComputeResourceId
   *   Preferences related to a particular compute resource
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userComputeResourceId
   */
  bool deleteUserComputeResourcePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userComputeResourceId) {
    // Your implementation goes here
    printf("deleteUserComputeResourcePreference\n");
  }

  /**
   * Delete the Storage Resource Preference of a registered user resource profile.
   * 
   * @param userId
   *   The identifier of the user profile to be deleted.
   * 
   * @param gatewayID
   *   The identifier to link a gateway for the requested user resource profile.
   * 
   * @param userStorageId
   *   ID of the storage preference you want to delete.
   * 
   * @return status
   *   Returns a success/failure of the deletion.
   * 
   * 
   * @param authzToken
   * @param userId
   * @param gatewayID
   * @param userStorageId
   */
  bool deleteUserStoragePreference(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& userId, const std::string& gatewayID, const std::string& userStorageId) {
    // Your implementation goes here
    printf("deleteUserStoragePreference\n");
  }

  void getLatestQueueStatuses(std::vector< ::apache::airavata::model::status::QueueStatusModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getLatestQueueStatuses\n");
  }

  /**
   * API Methods related to replica catalog
   * 
   * 
   * @param authzToken
   * @param dataProductModel
   */
  void registerDataProduct(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::data::replica::DataProductModel& dataProductModel) {
    // Your implementation goes here
    printf("registerDataProduct\n");
  }

  void getDataProduct( ::apache::airavata::model::data::replica::DataProductModel& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& dataProductUri) {
    // Your implementation goes here
    printf("getDataProduct\n");
  }

  void registerReplicaLocation(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::data::replica::DataReplicaLocationModel& replicaLocationModel) {
    // Your implementation goes here
    printf("registerReplicaLocation\n");
  }

  void getParentDataProduct( ::apache::airavata::model::data::replica::DataProductModel& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri) {
    // Your implementation goes here
    printf("getParentDataProduct\n");
  }

  void getChildDataProducts(std::vector< ::apache::airavata::model::data::replica::DataProductModel> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& productUri) {
    // Your implementation goes here
    printf("getChildDataProducts\n");
  }

  /**
   * Group Manager and Data Sharing Related API methods
   * 
   * 
   * @param authzToken
   * @param resourceId
   * @param userPermissionList
   */
  bool shareResourceWithUsers(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const std::map<std::string,  ::apache::airavata::model::group::ResourcePermissionType::type> & userPermissionList) {
    // Your implementation goes here
    printf("shareResourceWithUsers\n");
  }

  bool shareResourceWithGroups(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const std::map<std::string,  ::apache::airavata::model::group::ResourcePermissionType::type> & groupPermissionList) {
    // Your implementation goes here
    printf("shareResourceWithGroups\n");
  }

  bool revokeSharingOfResourceFromUsers(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const std::map<std::string,  ::apache::airavata::model::group::ResourcePermissionType::type> & userPermissionList) {
    // Your implementation goes here
    printf("revokeSharingOfResourceFromUsers\n");
  }

  bool revokeSharingOfResourceFromGroups(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const std::map<std::string,  ::apache::airavata::model::group::ResourcePermissionType::type> & groupPermissionList) {
    // Your implementation goes here
    printf("revokeSharingOfResourceFromGroups\n");
  }

  void getAllAccessibleUsers(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("getAllAccessibleUsers\n");
  }

  void getAllAccessibleGroups(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("getAllAccessibleGroups\n");
  }

  void getAllDirectlyAccessibleUsers(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("getAllDirectlyAccessibleUsers\n");
  }

  void getAllDirectlyAccessibleGroups(std::vector<std::string> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("getAllDirectlyAccessibleGroups\n");
  }

  bool userHasAccess(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourceId, const  ::apache::airavata::model::group::ResourcePermissionType::type permissionType) {
    // Your implementation goes here
    printf("userHasAccess\n");
  }

  void createGroupResourceProfile(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::groupresourceprofile::GroupResourceProfile& groupResourceProfile) {
    // Your implementation goes here
    printf("createGroupResourceProfile\n");
  }

  void updateGroupResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::groupresourceprofile::GroupResourceProfile& groupResourceProfile) {
    // Your implementation goes here
    printf("updateGroupResourceProfile\n");
  }

  void getGroupResourceProfile( ::apache::airavata::model::appcatalog::groupresourceprofile::GroupResourceProfile& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getGroupResourceProfile\n");
  }

  bool removeGroupResourceProfile(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("removeGroupResourceProfile\n");
  }

  void getGroupResourceList(std::vector< ::apache::airavata::model::appcatalog::groupresourceprofile::GroupResourceProfile> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getGroupResourceList\n");
  }

  bool removeGroupComputePrefs(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("removeGroupComputePrefs\n");
  }

  bool removeGroupComputeResourcePolicy(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourcePolicyId) {
    // Your implementation goes here
    printf("removeGroupComputeResourcePolicy\n");
  }

  bool removeGroupBatchQueueResourcePolicy(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourcePolicyId) {
    // Your implementation goes here
    printf("removeGroupBatchQueueResourcePolicy\n");
  }

  void getGroupComputeResourcePreference( ::apache::airavata::model::appcatalog::groupresourceprofile::GroupComputeResourcePreference& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& computeResourceId, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getGroupComputeResourcePreference\n");
  }

  void getGroupComputeResourcePolicy( ::apache::airavata::model::appcatalog::groupresourceprofile::ComputeResourcePolicy& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourcePolicyId) {
    // Your implementation goes here
    printf("getGroupComputeResourcePolicy\n");
  }

  void getBatchQueueResourcePolicy( ::apache::airavata::model::appcatalog::groupresourceprofile::BatchQueueResourcePolicy& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& resourcePolicyId) {
    // Your implementation goes here
    printf("getBatchQueueResourcePolicy\n");
  }

  void getGroupComputeResourcePrefList(std::vector< ::apache::airavata::model::appcatalog::groupresourceprofile::GroupComputeResourcePreference> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getGroupComputeResourcePrefList\n");
  }

  void getGroupBatchQueueResourcePolicyList(std::vector< ::apache::airavata::model::appcatalog::groupresourceprofile::BatchQueueResourcePolicy> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getGroupBatchQueueResourcePolicyList\n");
  }

  void getGroupComputeResourcePolicyList(std::vector< ::apache::airavata::model::appcatalog::groupresourceprofile::ComputeResourcePolicy> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& groupResourceProfileId) {
    // Your implementation goes here
    printf("getGroupComputeResourcePolicyList\n");
  }

  /**
   * GatewayGroups API methods
   * 
   * @param authzToken
   */
  void getGatewayGroups( ::apache::airavata::model::appcatalog::gatewaygroups::GatewayGroups& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken) {
    // Your implementation goes here
    printf("getGatewayGroups\n");
  }

  void getParser( ::apache::airavata::model::appcatalog::parser::Parser& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& parserId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getParser\n");
  }

  void saveParser(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::parser::Parser& parser) {
    // Your implementation goes here
    printf("saveParser\n");
  }

  void listAllParsers(std::vector< ::apache::airavata::model::appcatalog::parser::Parser> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("listAllParsers\n");
  }

  bool removeParser(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& parserId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("removeParser\n");
  }

  void getParsingTemplate( ::apache::airavata::model::appcatalog::parser::ParsingTemplate& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& templateId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getParsingTemplate\n");
  }

  void getParsingTemplatesForExperiment(std::vector< ::apache::airavata::model::appcatalog::parser::ParsingTemplate> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& experimentId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("getParsingTemplatesForExperiment\n");
  }

  void saveParsingTemplate(std::string& _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const  ::apache::airavata::model::appcatalog::parser::ParsingTemplate& parsingTemplate) {
    // Your implementation goes here
    printf("saveParsingTemplate\n");
  }

  bool removeParsingTemplate(const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& templateId, const std::string& gatewayId) {
    // Your implementation goes here
    printf("removeParsingTemplate\n");
  }

  void listAllParsingTemplates(std::vector< ::apache::airavata::model::appcatalog::parser::ParsingTemplate> & _return, const  ::apache::airavata::model::security::AuthzToken& authzToken, const std::string& gatewayId) {
    // Your implementation goes here
    printf("listAllParsingTemplates\n");
  }

};

int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<AiravataHandler> handler(new AiravataHandler());
  shared_ptr<TProcessor> processor(new AiravataProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
  server.serve();
  return 0;
}

